/*
   container/list

   List 链表的结构 :

   List [ 		  0, 			  1, 			  2, 		      3, 		      4, 		      5         ]
          [ p: nil, n: 1 ], [ p: 0, n: 2 ], [ p: 1, n: 3 ], [ p: 2, n: 4 ], [ p: 3, n: 5 ], [ p: 4, n: nil ]
   * 注 :

     Prev 		         		上一个元素
	 Next		         		下一个元素
	 Front 			     		头部元素
	 Back 			     		尾部元素
	 PushFront   	     		头部推入元素
	 PushFrontList       		头部推入List
     PushBack            		尾部推入元素
     PushBackList        		尾部推入List
     Len                 		元素长度
     InsertBefore        		在一个元素之前插入一个新元素
     InsertAfter         		在一个元素之后插入一个新元素
     MoveToFront         		移动一个元素到List头部
     MoveToBack          		移动一个元素到List尾部
     MoveBefore          		移动一个元素到另一个元素之前
     MoveAfter           		移动一个元素到另一个元素之后
     Remove              		移除一个List元素

*/

package main

import (
	"container/list"
	"fmt"
	"strconv"
)

func main() {

	// 创建list
	var l = list.New()

	// 从头部推入元素
	for i := 0; i < 10; i++ {
		l.PushFront(i)
	}

	// 查看结构
	printList(l, false)

	// 获取List长度
	fmt.Printf("---------- [ l 的元素长度 : %v ] ---------- \n", l.Len())

	/* 遍历List --------------------------------------------------------------------------------------------------------*/

	// 正向遍历
	fmt.Println("---------- [ 正向遍历 ] ----------")
	for e := l.Front(); e != nil; e = e.Next() {
		fmt.Println(e.Value)
	}

	// 反向遍历
	fmt.Println("---------- [ 反向遍历 ] ----------")
	for e := l.Back(); e != nil; e = e.Prev() {
		fmt.Println(e.Value)
	}

	/* 推入元素 ---------------------------------------------------------------------------------------------------------*/

	// 头部推入List
	var tmpList = list.New()
	for i := 9; i != 0; i-- {
		tmpList.PushFront(i)
	}
	fmt.Println("---------- [ 待推入的 List : ] ----------")
	printList(tmpList, false)

	// 头部推入 List 到原有 List
	l.PushFrontList(tmpList)
	fmt.Println("---------- [ 推入后的 List : ] ----------")
	printList(l, false)

	// 尾部推入元素
	var newL = list.New()
	for i := 0; i < 10; i++ {
		newL.PushBack(i)
	}
	fmt.Println("---------- [ 尾部推入的 List : ] ----------")
	printList(newL, false)

	// 尾部推入 List
	newL.PushBackList(tmpList)
	fmt.Println("---------- [ 尾部推入 List : ] ----------")
	printList(newL, false)
}

// 遍历打印 List
func printList(l *list.List, reverse bool) {
	var str = "[ "
	if reverse {
		for e := l.Back(); e != nil; e = e.Prev() {
			r, _ := e.Value.(int)
			str += strconv.Itoa(r) + ", "
		}
		str = str[0 : len(str)-2]
		str += " ]"
		fmt.Println(str)
	} else {
		for e := l.Front(); e != nil; e = e.Next() {
			r, _ := e.Value.(int)
			str += strconv.Itoa(r) + ", "
		}
		str = str[0 : len(str)-2]
		str += " ]"
		fmt.Println(str)
	}
}
